package device

import chisel3._
import chisel3.util._
import common.Constants._
import bus._

class RAMHelper(memByte: Int) extends BlackBox {
  val io = IO(new Bundle {
    val clk = Input(Clock())
    val rIdx = Input(UInt(DataBits.W))
    val rdata = Output(UInt(DataBits.W))
    val wIdx = Input(UInt(DataBits.W))
    val wdata = Input(UInt(DataBits.W))
    val wmask = Input(UInt(DataBits.W))
    val wen = Input(Bool())
  })
}

class AXI4RAM[T <: AXI4](_type: T = new AXI4, memByte: Int) extends AXI4SlaveModule(_type)
{

  val offsetBits = log2Up(memByte)
  val offsetMask = (1 << offsetBits) - 1
  def index(addr: UInt) = (addr & offsetMask.U) >> log2Ceil(DataBytes)
  def inRange(idx: UInt) = idx < (memByte / 8).U

  val wIdx = index(waddr) + writeBeatCnt
  val rIdx = index(raddr) + readBeatCnt
  val wen = in.w.fire() && inRange(wIdx)

  
  val mem = Module(new RAMHelper(memByte))
  mem.io.clk := clock
  mem.io.rIdx := rIdx
  mem.io.wIdx := wIdx
  mem.io.wdata := in.w.bits.data
  mem.io.wmask := fullMask
  mem.io.wen := wen
  val rdata = mem.io.rdata
  

  in.r.bits.data := RegEnable(rdata, ren)
}